package com.lbssoft.gpsbd.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lbssoft.datalink.EntityManager;
import com.lbssoft.datalink.entity.SyncDevice;
import com.lbssoft.datalink.util.Log;
import com.lbssoft.gpsbd.common.Constant;
import com.lbssoft.gpsbd.common.ErrorEnum;
import com.lbssoft.gpsbd.common.Utils;
import com.lbssoft.gpsbd.dao.DeviceMapper;
import com.lbssoft.gpsbd.dao.GroupMapper;
import com.lbssoft.gpsbd.datalink.Context;
import com.lbssoft.gpsbd.model.Device;
import com.lbssoft.gpsbd.model.Group;
import com.lbssoft.gpsbd.model.Result;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


@Aspect
@Component
public class SyncDeviceAspect {
    //使用org.slf4j.Logger,这是Spring实现日志的方法
    private final static Logger logger = LoggerFactory.getLogger(SyncDeviceAspect.class);
//
//    @Value("${gpsbd.appsecret}")
//    private String appsecret;
//
//    //采集中心实体管理器
//    EntityManager em =new EntityManager(appsecret);

    @Autowired
    DeviceMapper deviceMapper;

    @Autowired
    GroupMapper groupMapper;

    /**
     * 定义AOP扫描路径
     * 第一个注解只扫描aopTest方法
     */
    //@Pointcut("execution(public * com.aston.reader.controller.StudentController.*())")
    @Pointcut("execution(public * com.lbssoft.gpsbd.controller.DeviceController.delete(..)) || " +
            "execution(public * com.lbssoft.gpsbd.controller.DeviceController.add(..))|| " +
            "execution(public * com.lbssoft.gpsbd.controller.DeviceController.update(..))")
    public void device(){}

    /**
     * 记录HTTP请求开始时的日志
     */
    @Before("device()")
    public void doBefore(JoinPoint joinPoint){
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//        System.out.println("log");
//        //URL
//        logger.info("url={}", request.getRequestURI());
//        //method
//        logger.info("method={}", request.getMethod());
//        //ip
//        logger.info("ip={}",request.getRemoteAddr());
//        //类方法
//        logger.info("class={} and method name = {}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName());
//        //参数
//        logger.info("参数={}",joinPoint.getArgs());
    }

    /**
     * 记录HTTP请求结束时的日志
     */
    @After("device()")
    public void doAfter(){
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//        logger.info("url = {} end of execution", request.getRequestURL());
    }

    /**
     * 获取返回内容
     * @param object
     */
    @AfterReturning(returning = "object",pointcut = "device()")
    public void doAfterReturn(Object object){
//        logger.info("response={}",object.toString());
    }

    /**
     * 环绕通知（Around advice） ：包围一个连接点的通知，类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为，也可以选择不执行。
     * @param joinPoint
     */
    @Around("device()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable
    {
        com.lbssoft.datalink.model.Result res = new com.lbssoft.datalink.model.Result();
        Device device = new Device();
        Device localDevice;
        SyncDevice syncDevice = new SyncDevice();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        Method method = signature.getMethod(); //获取被拦截的方法
        String methodName = method.getName(); //获取被拦截的方法名
        //判断是否开启同步
        if (!Constant.DEV_MODE) {
            System.out.println("====同步开始=====");
            switch (methodName) {
                //添加设备
                case "add":
                    device = (Device) args[0];
                    syncDevice.setImei(device.getImei());
                    if(device.getGroupId()!=null&&device.getGroupId()!=0){
                        Group group = groupMapper.getGroupById(device.getGroupId());
                        syncDevice.setGroupUUID(group.getUuid());
                    }

                    res = Context.entityManager.addDevice(syncDevice);
                    if (res.getCode() != 0) {
                        return new Result(ErrorEnum.E_005.getErrorCode(), ErrorEnum.E_005.getErrorMsg(), "");
                    }
                    JSONObject data = JSON.parseObject(res.getData().toString());
                    device.setUuid(data.get("uuid").toString());
                    break;
                //更新超速
                case "update":
                    device = (Device) args[1];
                    localDevice = deviceMapper.getDeviceById(device.getId());
                    if(device.getSpeedLimit()!=localDevice.getSpeedLimit()){
                        if(localDevice.getGroupId()!=null&&localDevice.getGroupId()!=0){
                            Group group= groupMapper.getGroupById(localDevice.getGroupId());
                            syncDevice.setGroupUUID(group.getUuid());
                        }
                        syncDevice.setUuid(localDevice.getUuid());
                        syncDevice.setSpeedLimit(device.getSpeedLimit());
                        Log.info(JSON.toJSONString(syncDevice));
                        res = Context.entityManager.updateDevice(syncDevice);
                        if (res.getCode() != 0) {
                            return new Result(ErrorEnum.E_005.getErrorCode(), ErrorEnum.E_005.getErrorMsg(), "");
                        }
                    }
                    break;
                //删除设备
                case "delete":
                    long id = (long) args[0];
                    localDevice = deviceMapper.getDeviceById(id);
                    res = Context.entityManager.delDevice(localDevice.getUuid());
                    if (res.getCode() != 0) {
                        return new Result(ErrorEnum.E_005.getErrorCode(), ErrorEnum.E_005.getErrorMsg(), "");
                    }
                    break;
                default:

            }
            System.out.println("=====同步结束=====");
        }

        return  joinPoint.proceed();
    }

}